package com.typing.battle.async;

import java.io.BufferedInputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.SystemClock;
import android.widget.ImageView;

import com.typing.battle.R;
import com.typing.battle.util.KLog;
import com.typing.battle.util.ServerComunicationUtil;

public class ImageAsync extends AsyncTask<String, Integer, Bitmap> {
	
	private Context context;
	private ImageView iv;
	private String url;
	private int defaultImg = -1;
	
//	private ImageDBCache cachedDB = null;
	
	public static boolean isScrolling = false;
	private final static int CHECK_TIMEOUT = 10 * 1000;
	@SuppressWarnings("unchecked")
	private static HashMap<String, Bitmap>[] cachedImage = new HashMap[4];
	
	static {
		for (int i=0;i<cachedImage.length;i++) {
			if (cachedImage[i]==null) { 
				cachedImage[i] = new HashMap<String, Bitmap>();
			}
		}
	}
	
	public ImageAsync(Context context, String url, ImageView iv) {
		this.context = context;
//		cachedDB = ImageDBCache.getInstance(context);
		this.url = url;
		this.iv = iv;
		this.defaultImg = R.drawable.img_nophoto;
		initScreen();
	}
	
	public ImageAsync(Context context, String url, ImageView iv, int defaultImg) {
		this.context = context;
//		cachedDB = ImageDBCache.getInstance(context);
		this.url = url;
		this.iv = iv;
		this.defaultImg = defaultImg;
		initScreen();
	}
	
	private void initScreen() {
		if (containsKey(url)) {
			iv.setImageBitmap(getData(url));
		} else {
//			Bitmap bitmap = cachedDB.getUrlBitmap(url);
//			if (bitmap!=null) iv.setImageBitmap(bitmap);
//			else{
//				if(RWDeviceUtil.isICS())
//					executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
//				else
					execute();
//			}
		}
	}
	
	private boolean containsKey(String url) {
		for (int i=0;i<cachedImage.length;i++) {
			if (cachedImage[i].containsKey(url)) return true;
		}
		return false;
	}
	
	private Bitmap getData(String url) {
		for (int i=0;i<cachedImage.length;i++) {
			if (cachedImage[i].containsKey(url)) return cachedImage[i].get(url);
		}
		
		return null;
	}
	
	
	public void addBitmap(String url, Bitmap bitmap) {
		cachedImage[0].put(url, bitmap);
		
//		ByteArrayOutputStream  byteArray = new ByteArrayOutputStream();
//		bitmap.compress(CompressFormat.PNG, 100, byteArray);
//		byte[] b = byteArray.toByteArray();
//		cachedDB.insertUrlBitmap(url, b);
		
		if (cachedImage[0].size()>=50) {
			HashMap<String, Bitmap> tmp = cachedImage[cachedImage.length-1];
			for (int i=cachedImage.length-1;i>0;i--) {
				cachedImage[i] = cachedImage[i-1]; 
			}
			cachedImage[0] = new HashMap<String, Bitmap>();
			tmp.clear();
		}
	}
	
	public static void clear() {
		for (int i=0;i<cachedImage.length;i++) {
			cachedImage[i].clear();
		}
	}

	@Override
	protected Bitmap doInBackground(String... arg0) {
		if (url==null || url.length()<1) return null;

		if (isCancelled()) return null;
		
		while(isScrolling) {
			SystemClock.sleep(100);
		}
		
		Bitmap bm = null;
		try {
			if (containsKey(url)) return getData(url);
//			if (url.startsWith("content://")) {
//				bm = ImageUtilities.loadFromURI(context, url);
//			} else
			if (url.startsWith("/mnt")) {
				bm = BitmapFactory.decodeFile(url);
			} else {
				bm = getBitmapImage(url, false);
			}
		}catch (Exception e) {
			KLog.e(context, e);
		}
		return bm; 
	}

	@Override
	protected void onPostExecute(Bitmap tempData) {
		
		if (tempData==null) {
			if (isCancelled()==false) {
				if (defaultImg>-1) {
					iv.setImageResource(defaultImg);
				} else {
					iv.setImageBitmap(null);
				}
			}
		} else {
			addBitmap(url, tempData);
			if (isCancelled()==false) {
				iv.setImageBitmap(tempData);
			}
		}
	}
	private Bitmap getBitmapImage(String url, boolean downSampling) {
		Bitmap bm = null;
		HttpURLConnection conn = null;
		BufferedInputStream bis = null;
		if (url==null) return null;
		try {
			URL imageURL = ServerComunicationUtil.getUrls(url);
			conn = (HttpURLConnection) imageURL.openConnection();
			conn.setConnectTimeout(CHECK_TIMEOUT);
			bis = new BufferedInputStream(conn.getInputStream(), 1024);
			if (downSampling) {
				BitmapFactory.Options options = new BitmapFactory.Options();
				options.inSampleSize = 2;
//				options.inDither=false;                     //Disable Dithering mode
//				options.inPurgeable=true;                   //Tell to gc that whether it needs free memory, the Bitmap can be cleared
//				options.inInputShareable=true;              //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
//				options.inTempStorage=new byte[32 * 1024]; 
				bm = BitmapFactory.decodeStream(bis, null, options);
			} else {
				bm = BitmapFactory.decodeStream(bis);
			}
		} catch (Exception e) {
			KLog.e(context, e);
		} finally {
		      try {
		          if (bis != null)	bis.close();
		          if (conn != null)	conn.disconnect();
		        } catch (Exception e) {
		        	KLog.e(context, e);
		        }
		}
		return bm;
	}
}
